#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
教室分析模块
负责教室数据的分析和智能匹配
"""

import re
from typing import List, Dict, Any, Optional, Set, Tuple


class RoomAnalyzer:
    """教室分析器"""

    @staticmethod
    def find_similar_room(target_room: str, existing_rooms: List[str]) -> Optional[str]:
        """
        从现有教室中找到与目标教室最相似的

        Args:
            target_room: 目标教室名称
            existing_rooms: 现有教室列表

        Returns:
            最相似的教室名称，如果没有合适的匹配则返回None
        """
        try:
            print(f"[DEBUG] 智能匹配：目标教室 '{target_room}'，现有教室 {len(existing_rooms)} 个")

            # 1. 精确匹配：如果目标教室完全存在
            if target_room in existing_rooms:
                print(f"[DEBUG] 找到精确匹配: {target_room}")
                return target_room

            # 2. 提取目标教室的数字部分
            target_number_match = re.search(r'(\d+)', target_room)
            if not target_number_match:
                print(f"[DEBUG] 无法从目标教室 '{target_room}' 中提取数字")
                return None

            target_number = target_number_match.group(1)
            print(f"[DEBUG] 提取到教室编号: {target_number}")

            # 3. 按优先级排序寻找匹配
            scored_rooms = [(room, RoomAnalyzer._get_match_priority(room, target_room, target_number))
                           for room in existing_rooms]
            scored_rooms = [(room, score) for room, score in scored_rooms if score > 0]
            scored_rooms.sort(key=lambda x: x[1], reverse=True)

            if scored_rooms:
                best_match = scored_rooms[0][0]
                best_score = scored_rooms[0][1]
                print(f"[DEBUG] 最佳匹配: {best_match} (评分: {best_score})")

                # 如果匹配度过低，返回None
                if best_score < 50:
                    print(f"[DEBUG] 匹配度过低 ({best_score} < 50)，不返回建议")
                    return None

                # 返回基础名称（去掉容量信息）以便后续查询
                best_match_base = re.sub(r'\(\d+\)', '', best_match).strip()
                return best_match_base

            print(f"[DEBUG] 未找到合适的匹配教室")
            return None

        except Exception as e:
            print(f"[ERROR] 查找相似教室时出错: {e}")
            import traceback
            traceback.print_exc()
            return None

    @staticmethod
    def _get_match_priority(room: str, target_room: str, target_number: str) -> int:
        """
        计算匹配优先级

        Args:
            room: 候选教室（可能包含容量信息，如"东201(150)"）
            target_room: 目标教室
            target_number: 目标教室编号

        Returns:
            匹配优先级分数
        """
        # 提取教室的基础名称（去掉容量信息）
        room_base = re.sub(r'\(\d+\)', '', room).strip()
        room_lower = room.lower()
        room_base_lower = room_base.lower()
        target_lower = target_room.lower()

        # 最高优先级：完全匹配（包括容量信息）
        if room == target_room:
            return 100

        # 高优先级：基础名称完全匹配
        if room_base == target_room:
            return 98

        # 高优先级：包含完整目标字符串
        if target_lower in room_lower or target_lower in room_base_lower:
            return 90

        # 提取数字并检查匹配
        if target_number in room:
            target_locations = RoomAnalyzer._extract_location_info(target_room)
            room_locations = RoomAnalyzer._extract_location_info(room_base)

            # 特殊处理：如果目标包含"九教"，优先匹配"东"开头的教室
            if "九教" in target_room or "九" in target_room:
                if room.startswith("东"):
                    return 95  # 九教 -> 东XX 的高优先级匹配
                elif room_base.startswith("东"):
                    return 94  # 九教 -> 东XX 的高优先级匹配（基础名称）
                elif room_locations:
                    return 80  # 其他有位置信息的教室
                else:
                    return 70  # 纯数字匹配

            # 如果目标包含位置信息
            if target_locations:
                # 房间也有位置信息，检查是否匹配
                common_locations = set(target_locations) & set(room_locations)
                if common_locations:
                    return 85  # 位置匹配
                else:
                    return 65  # 数字匹配但位置不匹配
            else:
                # 目标没有位置信息，但房间有，给予中等优先级
                if room_locations:
                    return 60  # 可能是模糊查询
                else:
                    return 70  # 纯数字匹配

        # 中等优先级：仅包含相同数字
        if target_number in room:
            return 60

        # 低优先级：数字接近
        try:
            room_num = RoomAnalyzer._extract_number(room)
            diff = abs(room_num - int(target_number))
            if diff <= 10:  # 数字差10以内
                return 50 - diff
        except:
            pass

        return 0

    @staticmethod
    def _extract_location_info(room_str: str) -> List[str]:
        """
        提取位置信息

        Args:
            room_str: 教室名称

        Returns:
            位置信息列表
        """
        locations = ['东', '西', '南', '北', '中', '东南', '东北', '西南', '西北']
        room_lower = room_str.lower()

        found_locations = []
        for loc in locations:
            if loc in room_lower:
                found_locations.append(loc)

        return found_locations

    @staticmethod
    def _extract_number(room_str: str) -> int:
        """
        从教室名称中提取数字

        Args:
            room_str: 教室名称

        Returns:
            教室编号
        """
        match = re.search(r'(\d+)', room_str)
        return int(match.group(1)) if match else 0

    @staticmethod
    def extract_capacity(room_name: str) -> int:
        """
        从教室名称中提取容量

        Args:
            room_name: 教室名称

        Returns:
            教室容量
        """
        match = re.search(r'\((\d+)\)', room_name)
        return int(match.group(1)) if match else 0

    @staticmethod
    def find_continuous_sequences(sections: Set[int]) -> List[List[int]]:
        """
        找出连续的节次段

        Args:
            sections: 节次集合

        Returns:
            连续节次段列表
        """
        sections_list = sorted(sections)
        sequences = []

        if not sections_list:
            return sequences

        current_seq = [sections_list[0]]
        for i in range(1, len(sections_list)):
            if sections_list[i] == sections_list[i - 1] + 1:  # 连续
                current_seq.append(sections_list[i])
            else:  # 不连续，开始新序列
                sequences.append(current_seq)
                current_seq = [sections_list[i]]
        sequences.append(current_seq)  # 添加最后一个序列

        return sequences

    @staticmethod
    def analyze_room_availability(rooms_info: List[Dict[str, Any]],
                                 selected_weekdays: List[int],
                                 selected_sections: List[int],
                                 target_room: str = "") -> Dict[str, Any]:
        """
        分析教室可用性

        Args:
            rooms_info: 教室信息列表
            selected_weekdays: 选择的星期
            selected_sections: 选择的节次
            target_room: 目标教室（可选）

        Returns:
            分析结果
        """
        # 过滤用户选择的时间段
        filtered_info = [
            info for info in rooms_info
            if info['day'] in selected_weekdays and info['section'] in selected_sections
        ]

        if target_room:
            # 特定教室分析
            room_info = [info for info in filtered_info if info['room'].startswith(target_room)]
            return {
                'is_target_room': True,
                'target_room_info': room_info,
                'all_rooms': list(set(info['room'] for info in filtered_info)),
                'free_rooms': [info for info in room_info if info['is_free']]
            }
        else:
            # 普通教室分析
            free_rooms = [info for info in filtered_info if info['is_free']]
            all_rooms = list(set(info['room'] for info in filtered_info))

            return {
                'is_target_room': False,
                'all_rooms': all_rooms,
                'free_rooms': free_rooms,
                'total_rooms_count': len(all_rooms),
                'free_rooms_count': len(free_rooms)
            }